
clear all;
close all;

TEST_TYPE_NAMES = { "symbolic", "fdiff" };

A = cell(2, 1);
EVAL_PARAMS = cell(2, 1);

A{1} = { "gsl_ext_bfgs_mt", ...
         "gsl_ext_bfgs_f", ...
         "gsl_vector_bfgs2", ...
         "gsl_ext_mnewton", ...
         "gsl_ext_conjgrad_fr_mt", ...
         "gsl_ext_conjgrad_pr_mt", ...
         "gsl_vector_bfgs", ...
         "gsl_conjugate_fr", ...
         "gsl_conjugate_pr" };

EVAL_PARAMS{1} = struct("f", "sym", "g", "sym", "H", "sym");

A{2} = { "gsl_ext_bfgs_mt", ...
         "gsl_ext_bfgs_f", ...
         "gsl_vector_bfgs2", ...
         "gsl_ext_mnewton", ...
         "gsl_ext_conjgrad_fr_mt", ...
         "gsl_ext_conjgrad_pr_mt", ...
         "gsl_vector_bfgs", ...
         "gsl_conjugate_fr", ...
         "gsl_conjugate_pr", ...
         "gsl_ext_lrwwsimplex", ...
         "gsl_nmsimplex" };

EVAL_PARAMS{2} = struct("f", "precomp", "g", "fd", "H", "fd");

TF = GSLpp_testfunctions();
TFI = [ 3, 4, 8, 16 ];

for tfi = TFI
  tf_params = GSLpp_get_testfunction_params(TF{tfi});

  if strcmp(typeinfo(TF{tfi}.starting_point), "function handle") == 1
    x_min = feval(TF{tfi}.minimizer, TF{tfi}.n);
  else
    x_min = TF{tfi}.minimizer;
  endif

  if strcmp(typeinfo(TF{tfi}.starting_point), "function handle") == 1
    x0 = feval(TF{tfi}.starting_point, TF{tfi}.n);
  else
    x0 = TF{tfi}.starting_point;
  endif
  
  for ti = 1:2
    results_table = cell(length(A{ti}) + 1, 6);
    column_widths = [ 30, 6, 6, 6, 6, 6 ];
    results_table{1, 1} = "Algorithm";
    results_table{1, 2} = "i";
    results_table{1, 3} = "f";
    results_table{1, 4} = "f/i";
    results_table{1, 5} = "g";
    results_table{1, 6} = "g/i";

    for ai = 1:length(A{ti})
      results = GSLpp_minimize(A{ti}{ai}, struct, struct, ...
                               TF{tfi}.name, tf_params, ...
                               EVAL_PARAMS{ti}, ...
                               "xdisttomin", ...
                               struct("eps", 1e-8, "xmin", x_min), ...
                               x0, 0, false);

      results_table{ai + 1, 1} = A{ti}{ai};

      if results.numiter < 10000
        results_table{ai + 1, 2} = results.numiter;
        results_table{ai + 1, 3} = results.nfeval;
        results_table{ai + 1, 4} = results.nfeval / results.numiter;
        results_table{ai + 1, 5} = results.ngeval;
        results_table{ai + 1, 6} = results.ngeval / results.numiter;
      else
        results_table{ai + 1, 2} = "F";
        results_table{ai + 1, 3} = "-";
        results_table{ai + 1, 4} = "-";
        results_table{ai + 1, 5} = "-";
        results_table{ai + 1, 6} = "-";
      endif
    endfor

    fp = fopen([ "iteration_statistics_", TEST_TYPE_NAMES{ti}, "_", TF{tfi}.name, ".txt" ], "w");
    GSLpp_print_results_table(results_table, column_widths, fp, "normal");  
    fclose(fp);
  endfor
endfor
